CloudFormation으로 ALB 액세스 로그 설정해 보기
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 CloudFormation으로 ALB 액세스 로그 설정해 보는 방법을 정리해 봤습니다.
액세스 로그
Elastic Load Balancing은 로드 밸런서에 전송된 요청에 대한 자세한 정보를 캡처하는 액세스 로그를 제공합니다. 각 로그에는 요청을 받은 시간, 클라이언트의 IP 주소, 지연 시간, 요청 경로 및 서버 응답과 같은 정보가 포함되어 있습니다. 이러한 액세스 로그를 사용하여 트래픽 패턴을 분석하고 문제를 해결할 수 있습니다.
액세스 로그는 다음과 같은 로그 정보를 담고 있습니다.
- 요청을 받은 시간
- 클라이언트의 IP 주소
- 지연 시간
- 요청 경로
- 서버 응답
bucket[/prefix]/AWSLogs/aws-account-id/elasticloadbalancing/region/yyyy/mm/dd/aws-account-id_elasticloadbalancing_region_app.load-balancer-id_end-time_ip-address_random-string.log.gz
액세스 로그의 경우 S3 버킷에 다음과 같은 경로에 저장됩니다.
보다 상새한 내용은 아래 문서를 참고해 주세요.
Management Console에서 액세스 로그 활성화
ALB를 생성할 때 액세스 로그를 설정하는 것은 불가능합니다.
ALB를 생성할 때 설정할 수 있는 부분은 다음과 같습니다.
- 로드 밸런서 이름
- 체계(내부 로드밸런서, 외부 로드밸런서)
- IP 주소 유형
- 네트워크 매핑
- 보안 그룹
- 타겟 그룹
- 리스너
- AWS Global Accelerator 설정 유무
등을 설정할 수 있지만, 액세스 로그를 설정할 수는 없습니다.
액세스 로그를 설정하기 위해, ALB를 생성한 다음「속성」→「편집」을 클릭합니다.
이어서 모니터링에서 액세스 로그를 활성화할 수 있습니다.
CloudFormation으로 액세스 로그 활성화
# ------------------------------------------------------------# # Create S3 Bucket # ------------------------------------------------------------# Resources: ALBLogsBucket: Type: "AWS::S3::Bucket" Properties: BucketName: !Sub ${SystemName}-${EnvName}-aws-alb-logs-bucket PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true LifecycleConfiguration: Rules: - Id: !Sub ${SystemName}-${EnvName}-aws-alb-logs-lifecycle Status: Enabled ExpirationInDays: 90 Tags: - Key: Name Value: !Sub ${SystemName}-${EnvName}-aws-alb-logs-bucket - Key: Env Value: !Sub ${EnvName} # ------------------------------------------------------------# # Set S3 Bucket Policy # ------------------------------------------------------------# ELBLogBucketPolicy: Type: "AWS::S3::BucketPolicy" Properties: Bucket: !Ref ALBLogsBucket PolicyDocument: Id: "AWSCFn-AccessLogs-Policy-20180920" Version: "2012-10-17" Statement: - Sid: "AlbLogs" Effect: "Allow" Action: - "s3:PutObject" Resource: !Sub arn:aws:s3:::${ALBLogsBucket}/AWSLogs/${AWS::AccountId}/* Principal: AWS: - "582318560864"
먼저 CloudFormation에서 S3 버킷을 생성하고, Policy를 설정합니다.
# ------------------------------------------------------------# # internet-facing ALB # ------------------------------------------------------------# InternetFacingALB: Type: "AWS::ElasticLoadBalancingV2::LoadBalancer" Properties: Name: !Sub ${SystemName}-${EnvName}-web-alb Tags: - Key: Name Value: !Sub ${SystemName}-${EnvName}-web-alb - Key: Env Value: !Sub ${EnvName} Scheme: "internet-facing" LoadBalancerAttributes: - Key: "deletion_protection.enabled" Value: true # trueに変更 - Key: access_logs.s3.enabled Value: true - Key: access_logs.s3.bucket Value: !Ref ALBLogsBucket - Key: "idle_timeout.timeout_seconds" Value: 60 SecurityGroups: - Fn::ImportValue: !Sub ${EnvName}-alb-sg Subnets: - Fn::ImportValue: !Sub ${EnvName}-public-subnet-1a - Fn::ImportValue: !Sub ${EnvName}-public-subnet-1c Type: application ALBListenerHTTPSWeb001: Type: AWS::ElasticLoadBalancingV2::Listener Properties: Port: 443 Protocol: HTTPS Certificates: - CertificateArn: !Ref LoadBalancerCertificateARN DefaultActions: - TargetGroupArn: !Ref TargetGroupWeb001 Type: forward LoadBalancerArn: !Ref InternetFacingALB
ALB를 생성하는 부분에서는「Key: access_logs.s3.enabled」를 활성화 하고,「Key: access_logs.s3.bucket」에 로그를 저장할 S3 버킷을 설정합니다.
AWSTemplateFormatVersion: "2010-09-09" Description: Create ALB or S3 Bucket # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Description: "System name of each resource names." Type: String Default: "test" EnvName: Description: "Environment name of each resource names." Type: String Default: "prd" HostZoneId: Description: FQDN of the hosted zone Type: AWS::Route53::HostedZone::Id Default: "xxxxxxxxxxxxxxxx" #Route53 HostedZone ID SubDomain: Description: FQDN of the certificate Type: String Default: "xxxxxxxxxxxxxx" #domain address to be used LoadBalancerCertificateARN: Type: String Default: "xxxxxxxxxxxxxxxxxxxx" #certificate ARN Description: Enter certificate ARN; Use ACM to create a certificate before creating this stack # ------------------------------------------------------------# # Create S3 Bucket # ------------------------------------------------------------# Resources: ALBLogsBucket: Type: "AWS::S3::Bucket" Properties: BucketName: !Sub ${SystemName}-${EnvName}-aws-alb-logs-bucket PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true LifecycleConfiguration: Rules: - Id: !Sub ${SystemName}-${EnvName}-aws-alb-logs-lifecycle Status: Enabled ExpirationInDays: 90 Tags: - Key: Name Value: !Sub ${SystemName}-${EnvName}-aws-alb-logs-bucket - Key: Env Value: !Sub ${EnvName} # ------------------------------------------------------------# # Set S3 Bucket Policy # ------------------------------------------------------------# ELBLogBucketPolicy: Type: "AWS::S3::BucketPolicy" Properties: Bucket: !Ref ALBLogsBucket PolicyDocument: Id: "AWSCFn-AccessLogs-Policy-20180920" Version: "2012-10-17" Statement: - Sid: "AlbLogs" Effect: "Allow" Action: - "s3:PutObject" Resource: !Sub arn:aws:s3:::${ALBLogsBucket}/AWSLogs/${AWS::AccountId}/* Principal: AWS: - "582318560864" # ------------------------------------------------------------# # Target Group # ------------------------------------------------------------# TargetGroupWeb001: Type: "AWS::ElasticLoadBalancingV2::TargetGroup" Properties: VpcId: Fn::ImportValue: !Sub ${EnvName}-vpc Name: !Sub ${SystemName}-${EnvName}-web001-tgp Protocol: HTTP Port: 80 HealthCheckProtocol: HTTP HealthCheckPath: "/" HealthCheckPort: "traffic-port" HealthyThresholdCount: 5 # 正常の閾値 UnhealthyThresholdCount: 2 # 非正常の閾値 HealthCheckTimeoutSeconds: 5 # タイムアウト HealthCheckIntervalSeconds: 60 # 間隔 Matcher: HttpCode: 200 # 成功コード Tags: - Key: Name Value: !Sub ${SystemName}-${EnvName}-web001-tgp - Key: Env Value: !Sub ${EnvName} TargetGroupAttributes: - Key: "stickiness.enabled" Value: false Targets: - Id: Fn::ImportValue: !Sub ${EnvName}-web Port: 80 # ------------------------------------------------------------# # internet-facing ALB # ------------------------------------------------------------# InternetFacingALB: Type: "AWS::ElasticLoadBalancingV2::LoadBalancer" Properties: Name: !Sub ${SystemName}-${EnvName}-web-alb Tags: - Key: Name Value: !Sub ${SystemName}-${EnvName}-web-alb - Key: Env Value: !Sub ${EnvName} Scheme: "internet-facing" LoadBalancerAttributes: - Key: "deletion_protection.enabled" Value: true # trueに変更 - Key: access_logs.s3.enabled Value: true - Key: access_logs.s3.bucket Value: !Ref ALBLogsBucket - Key: "idle_timeout.timeout_seconds" Value: 60 SecurityGroups: - Fn::ImportValue: !Sub ${EnvName}-alb-sg Subnets: - Fn::ImportValue: !Sub ${EnvName}-public-subnet-1a - Fn::ImportValue: !Sub ${EnvName}-public-subnet-1c Type: application ALBListenerHTTPSWeb001: Type: AWS::ElasticLoadBalancingV2::Listener Properties: Port: 443 Protocol: HTTPS Certificates: - CertificateArn: !Ref LoadBalancerCertificateARN DefaultActions: - TargetGroupArn: !Ref TargetGroupWeb001 Type: forward LoadBalancerArn: !Ref InternetFacingALB # ------------------------------------------------------------# # Route53 # ------------------------------------------------------------# DnsRecord: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Sub ${HostZoneId} Comment: "DNS for ALB" Name: !Sub ${SubDomain} Type: A AliasTarget: HostedZoneId: !GetAtt 'InternetFacingALB.CanonicalHostedZoneID' DNSName: !GetAtt 'InternetFacingALB.DNSName'
전체 코드는 다음과 같습니다. S3 버킷 생성 후, 액세스 로그 설정 뿐만 아니라 https 설정도 하고 있는 상태입니다.
액세스 로그 확인
CloudFormation을 생성한 다음, ALB를 확인해 보면, 액세스 로그가 활성화 되어 있는 것을 확인할 수 있습니다.
S3 버킷에서는 AWSLogs라는 객체가 생성되고「ELBAccessLogTestFile」파일이 생성된 것을 확인할 수 있습니다.
여기서 ALB에 몇 번 액세스를 시도해 보면, 날짜 별로 로그 파일이 생성됩니다.
본 블로그 게시글을 읽고 궁금한 사항이 있으신 분들은 [email protected]로 보내주시면 감사하겠습니다.